
package cell

import (
	"github.com/treelab/updatecolumn/models"
)

// InstanceType of cell
func InstanceType() int32 {
	return models.Text
}

  getText(cell: Cell) {
    return cell ? cell.text : '';
  }

  cellValueToString({ cell }: IColumnAndCell) {
    return this.getText(cell)?.trim() ?? '';
  }

  cellValueToNumber({ cell }: IColumnAndCell) {
    const result = parseFloat((this.getText(cell) || '').replace(/[^0-9.-]/g, '') ?? '0');
    return isNaN(result) ? 0 : result;
  }

  cellValueToRating(cell: IColumnAndCell) {
    // text cell con't convert to rate if it's text con't parse to a number
    if (isNaN(parseFloat(this.getText(cell.cell) || ''))) {
      return 0;
    }
    return Math.round(this.cellValueToNumber(cell));
  }

  cellValueToDatetime({ cell }: IColumnAndCell) {
    return this.getText(cell)?.trim() ?? '';
  }

  cellValueToCheckbox({ cell }: IColumnAndCell) {
    const text = this.getText(cell);
    return text === 'true' || text === 'checked';
  }

  cellValueToSelect({ column, cell }: IColumnAndCell) {
    const text = this.getText(cell);
    const option = _.find(column.hasColumnOption.get(), i => _.trim(i.name) === _.trim(text));
    return option;
  }

  cellValueToMultiSelect({ column, cell }: IColumnAndCell): any[] {
    const text = this.getText(cell);
    const texts = _.uniq(text?.split(',').map((subtext: string) => subtext.trim()));
    const options = _.filter(column.hasColumnOption.get(), i =>
      texts.find((findText: string) => _.trim(i.name) === findText),
    );
    return options;
  }

  cellValueToCollaborator({ cell, column, userGroup }: { cell: Cell; column: Column; userGroup: any }) {
    const userGroups = userGroup?.groups || [];
    const groups: any[] = [];
    const users = (cell.text || '').split(',');
    _.forEach(users, user => {
      const find = this.findCollaboratorGroupAndUser(userGroups, (user || '').trim(), ['name', 'email']);
      if (find) {
        groups.push(find);
      }
    });
    return _.uniq(groups);
  }

  setCellValue({ cell, action }: ICCAction) {
    cell.text = (action.value as TextCellValue).text;
    return this;
  }

  getCellValue(cell: Cell) {
    return cell.text;
  }

  emptyCells(command: UpdateColumn_v2, cells: readonly Cell[], deleteCells: boolean, o: CommonOptions) {
    if (!deleteCells) {
      _.forEach(cells, cell => {
        o.delQuads.push(...this.dgraphHelperService.getRemoveObjectQuads(cell.uid!, 'text'));
      });
    }
    super.emptyCells(command, cells, deleteCells, o);
    return this;
  }

  // 方法开始的时候, 传进来的 cell 和 column 还都是原始的类型,
  // 比如说 select 的 cc, 那么转成 text ,就会在 TEXT 里面用 convert
  convertCell(
    command: UpdateColumn_v2,
    o: CommonOptions,
    { columnCopy, userGroup, referenceColumns }: { columnCopy: Column; referenceColumns?: Column[]; userGroup: any },
  ) {
    const { column, columnConfig } = command;
    const { type: toType } = columnConfig;
    const { columnType: fromType } = columnCopy;

    if (toType === fromType) {
      return this;
    }

    const cells = column.hasCell.get();
    const SourceCells = columnCopy.hasCell.get();
    const events = new EventHelper();
    const fromCellHandle = this.instanceFactory.getCellInstance(fromType as ColumnType);
    if (this.needEmptyCell(command)) {
      fromCellHandle.emptyCells(command, cells, false, o);
    }
    if (cells.length) {
      const visableNameMapping = new Map<string, string>();
      _.forEach(cells, cell => {
        const action: UpdateCellAction = {
          type: UpdateAction.SET_VALUE,
          value: { ...command.columnConfig, type: toType },
        };
        const value = action.value as TextCellValue;
        cell.cellType = cell.cellType || get(cell.fromColumn.get()[0], 'columnType');
        if (cell.cellType) {
          const _cell = SourceCells.find(c => c.uid === cell.uid);
          if (_cell) {
            value.text = fromCellHandle.cellValueToString(
              {
                column: columnCopy,
                // @ TODO There are performance issues here, need to think of ways to fix
                cell: _cell,
                userGroup,
              },
              column.columnType,
            );
            const updateCell = {
              ...command,
              action,
              _metadata: { ...command._metadata, source: Source.SAGA },
            };
            const rowData = super.upsertCell(cell, { command: updateCell }, { ...o, events }, { columnCopy });
            if (rowData) {
              visableNameMapping.set(rowData.uid, rowData.visibleName);
            }
          }
        } else {
          const errorMsg = `Cell ${cell.uid!} CellType undefined,should be add cellType`;
          Logger.error(errorMsg);
          throw new Error(errorMsg);
        }
      });
      this.updateReferenceColumnAndDependencies({
        column,
        visableNameMapping,
        o,
        _metadata: command._metadata,
        referenceColumns,
      });
    }

    o.events.bulkAddEvents(...events);
    return this;
  }

